package com.db.common.aspect;

import com.db.common.annotation.RequiredMenu;
import com.db.common.util.IPUtils;
import com.db.pojo.SysLog;
import com.db.service.SysLogService;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.lang.reflect.Method;
import java.util.Arrays;

@Aspect
@Component
public class SysMenuAspect {

	@Autowired
	private SysLogService sysLogService;

	@Pointcut("bean(sysMenuServiceImpl)")
	public void doAspect() {
	}

	@Around("doAspect()")
	public Object dpAround(ProceedingJoinPoint jp) throws Throwable {

		long start = System.currentTimeMillis();
		Object proceed = jp.proceed();
		long end = System.currentTimeMillis();

		saveLog(jp, (end - start));

		return proceed;
	}

	private void saveLog(ProceedingJoinPoint jp, long time) throws Exception {

		SysLog sysLog = new SysLog();
		sysLog.setUsername("admin");
		sysLog.setTime(time);
		sysLog.setParams(Arrays.toString(jp.getArgs()));
		sysLog.setOperation(getOperation(jp));
		sysLog.setMethod(getMethod(jp));
		sysLog.setIp(IPUtils.getIpAddr());

		sysLogService.insertObject(sysLog);
	}

	private String getOperation(ProceedingJoinPoint jp) throws Exception {
		Class<?> clazz = jp.getTarget().getClass();
		MethodSignature signature = (MethodSignature) jp.getSignature();
		Method method = clazz.getMethod(signature.getName(), signature.getParameterTypes());

		RequiredMenu annotation = method.getAnnotation(RequiredMenu.class);
		if (annotation == null)
			return "operation";
		return annotation.operation();
	}

	private String getMethod(ProceedingJoinPoint jp) {
		Class<?> clazz = jp.getTarget().getClass();
		String className = clazz.getName();
		Signature signature = jp.getSignature();
		String methodName = signature.getName();

		return className + "." + methodName;
	}
}
